home *** CD-ROM | disk | FTP | other *** search
/ The CICA Windows Explosion! / The CICA Windows Explosion! - Disc 2.iso / programr / utexec2.zip / README.TXT next >
Text File  |  1994-07-12  |  8KB  |  182 lines

  1. Disclaimer:
  2.  
  3. The mind boggles thinking how intelligent the 
  4. programmer's at Microsoft must be. How can I, a 
  5. lowly mortal with no stock options, understand the 
  6. awe inspiring intellect of those whose boots I am 
  7. unworthy to lick? They must have wisdom that far 
  8. outstrips mine, since they graced us with the 
  9. inability to run a program and wait for it to finish. 
  10. How my heart aches to reach even the foothills of 
  11. their mountainous insight, the heights of which I am 
  12. unable to see. Oh Great Microsoft! What plan could 
  13. the High Microsoft Priests be leading us towards that 
  14. I am blinded to by my ignorance? Here am I, 
  15. floundering with small pieces of a puzzle that I 
  16. surely could never comprehend. Oh great Bill! Oh 
  17. great denizens of Microsoft! I am filled with joyous 
  18. rapture knowing your awe inspiring gray matter 
  19. permeates my universe! I hope that I, ignorant 
  20. heathen that I am, do not force programmer's to stray 
  21. from the Holy Plan Of Microsoft. I hope that I, 
  22. ignorant heathen that I am, do not force 
  23. programmer's off the One True Way, the way lead by 
  24. the Omniscient Bill! I pray to Redmond that my 
  25. feeble attempts will please the great Bill!
  26.  
  27. Documentation:
  28.  
  29. Under good old Windows all that has to be done to 
  30. execute a program and wait for it to terminate was a 
  31. WinExec. We would then either play with the 
  32. toolhelp DLL, or enumerate through all of the 
  33. windows in the system to find the one whose 
  34. instance handle we where given. This information 
  35. can be used to spin lock on the window disappearing 
  36. or the task that the window represents terminating. 
  37. This method works for both 16bit Windows 
  38. programs and 32bit Windows programs when using 
  39. Watcom's 32bit window's compiler. Watcom has 
  40. done a much better job than Microsoft's single entry 
  41. approach via the Universal Thunk interface, by the 
  42. way.
  43.  
  44. When under NT, a call to CreateProcess and 
  45. WaitForSingleObject is all that is needed. The only 
  46. slightly slippery problem occurs when CreateProcess 
  47. starts up an application that requires NT to load 
  48. another subsystem. You are given what is called a 
  49. pseudo handle instead of a normal process handle. 
  50. There is not much you can do with a pseudo handle, 
  51. but you can WaitForSingleObject on it. Praise be to 
  52. the Glory of Microsoft that they added this 
  53. capability.
  54.  
  55. When under WIN32S, you can only use 
  56. CreateProcess to start up other 32bit Windows 
  57. programs. 16bit Windows programs just will not 
  58. start. Do not bother looking at the error codes to see 
  59. what happened, because they indicate that everything 
  60. worked just fine. Even if you could reliably use 
  61. CreateProcess, WaitForSingleObject does not exist 
  62. under WIN32S. You could possibly try using 
  63. GetExitCodeProcess, but once again this works for 
  64. 32bit programs but does not work on 16bit ones. The 
  65. only thing you can do to consistently start another 
  66. program is WinExec. Unfortunately the return value 
  67. from WinExec is practically meaningless. Under 
  68. normal Windows, this is the instance handle of the 
  69. program that you just started if it is greater than 32, 
  70. otherwise it is an error code. Under WIN32S the 
  71. value returned can still be one of those 32 error 
  72. codes, but any successful invocation returns 33. This 
  73. gives us the ability to launch programs without the 
  74. ability of knowing exactly what program we just 
  75. launched.
  76.  
  77. This leaves us with only one way to successfully 
  78. launch a program and get any information back from 
  79. the launch. It has to be done under 16bit Windows. 
  80. Consequently, we have to invoke the Universal 
  81. Thunk in order to start up a 16bit DLL that will do 
  82. all of the dirty work for us. At this point you can use 
  83. one of the previously mentioned Windows methods for waiting 
  84. on a program to terminate. I decided that this 16bit 
  85. DLL would 1) Start up the program and retrieve it's 
  86. instance handle. 2) From that instance handle, find 
  87. the appropriate window handle. 3) Keep track of that 
  88. window handle and notify us when it or it's 
  89. associated task has terminated. This seems more 
  90. straight forward that using the toolhelp DLL 
  91. functions.
  92.  
  93. I will not go into the gory details of how to invoke 
  94. Universal Thunks, as there are better articles on that 
  95. process elsewhere. I will explain the interface to this 
  96. particular 16bit DLL, and suffice it to say that the 
  97. goofy parameter passing stuff is a requirement when 
  98. communicating through the Universal Thunk 
  99. interface. The only strange thing is the requirement 
  100. for the calling routine to allocate a chunk of space 
  101. that the DLL uses to store all of its data. This 
  102. requirement allows the DLL to be reentrant, and 
  103. subsequently allow access to it by multi-threaded 
  104. programs.
  105.  
  106. The first entry point of the 16bit DLL returns the 
  107. size of the data area that the calling program needs 
  108. to allocate. This space will be used by the DLL to 
  109. store any relevant data. The second entry point uses 
  110. this data storage space, and a string that the DLL 
  111. will try to execute. The standard Universal Thunk 
  112. pointer nonsense has to be done. It is important to 
  113. note that pointers are translated in place, which 
  114. would preclude their use after any call through the 
  115. Universal Thunk. The third entry point tells the 
  116. calling program if the application that it started is 
  117. still running. Using these three entry points, you can 
  118. start up any program under WIN32S and wait for it 
  119. to terminate. The actual code that does all of this is 
  120. located in the file 'run32.c.' All of the information 
  121. that you need to interface with Universal Thunks in 
  122. general and the run16 DLL in particular is located in 
  123. this file.
  124.  
  125. The run16 DLL was built using Visual C++ under 
  126. the large memory model, but it is a pretty generic 
  127. DLL that can be built using any decent compiler 
  128. tool. The only thing of note is that any routine that is 
  129. exported out of any DLL must have the __export 
  130. keyword, along with the __pascal calling 
  131. convention. Mystery lockups will happen if either of 
  132. those requirements are ignored. All of the code for 
  133. the DLL is in the file 'run16.c' and it's accompanying 
  134. 'run16.def' file.
  135.  
  136. The run32 DLL was also built using Visual C++. 
  137. Note that the memory allocation call was done using 
  138. the often maligned GlobalAlloc. If a call to the 
  139. standard C runtime library malloc was used, 
  140. various invocations of a mystery function called 
  141. _CRT_INIT would have to be added to the DLL's 
  142. entry point in order to initialize the C runtime 
  143. library. Adding these calls also eliminates the undocumented 
  144. linker error that results. The run32 DLL can be 
  145. invoked from any 32bit program. A simple call to 
  146. the TryExec entry point sets all of the mysterious 
  147. wheels of Universal Thunks in motion. It is 
  148. generally a good idea to place any invocation of the 
  149. Universal Thunk nonsense in a separate DLL. Not 
  150. only does it hide it's rather bizarre invocation, it also 
  151. allows the use of multiple Universal Thunks. Buried 
  152. in the bowels of the Universal Thunk documentation 
  153. is the rather curious fact that only one Universal 
  154. Thunk can exist for any EXE or DLL. This is 
  155. another shining example of Band-Aid programming, 
  156. but one that is easily covered worked around.
  157.  
  158. Both files need to have access to the WIN32S 
  159. Universal Thunk .h and .lib files when they are built.
  160.  
  161. It is my hope that by donating this code to the public 
  162. domain, people will use it as an example of how to 
  163. execute and wait for a program under WIN32S. If 
  164. this code saves another programmer from the time it 
  165. took me to find ANY solution, then I will be happy. I 
  166. hereby release all rights to this code and any derived 
  167. work, do not sue me, etc, etc, #include 
  168. <std.disclaimer>. I have also included the compiled 
  169. DLL's, in case anyone does not have access to a C 
  170. compiler. This should not imply that these files are 
  171. production quality code. I would hope that anyone 
  172. that really wants to use these routines would add a 
  173. bit more error checking...
  174.  
  175. In the name of Bill,
  176.  
  177. Timothy A. Anderson
  178. CI$ 72657,3330
  179. PO Box 6659
  180. Beaverton, OR 97007
  181.  
  182.